﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using COFE.IO.SZ.Utils;
using SevenZip;
using COFE.Core;
using System.Text.RegularExpressions;
using COFE.Core.Utils;
using COFE.Core.Profile;

namespace COFE.IO.SZ
{
    public class SZEntryInfo : IEquatable<SZEntryInfo>
    {
        #region Constructor

        /// <summary>
        /// Construct root.
        /// </summary>
        /// <param name="userProfile"></param>
        /// <param name="rootFile"></param>
        public SZEntryInfo(IInternalFileInfoExA rootFile)
        {
            ListerKey = rootFile.ListerKey;
            RootWrapper = new SevenZipWrapper(rootFile);
            _currentItem = new ArchiveFileInfo() { FileName = "", IsDirectory = true,  Size = (ulong)rootFile.Length, 
                CreationTime = rootFile.CreationTime, LastAccessTime = rootFile.LastAccessTime, LastWriteTime = rootFile.LastWriteTime };
            _isRoot = true;
        }

        /// <summary>
        /// Construct subitem.
        /// </summary>
        /// <param name="userProfile"></param>
        /// <param name="rootFile"></param>
        /// <param name="currentItem"></param>
        public SZEntryInfo(SevenZipWrapper rootWrapper, ArchiveFileInfo currentItem)
        {            
            RootWrapper = rootWrapper;
            ListerKey = rootWrapper.ArchiveFile.ListerKey;
            _currentItem = currentItem;
            _isRoot = false;
        }

        #endregion

        #region Methods

        private string getTempPath()
        {
            return _isRoot ?
                 COFEPath.Combine(COFEShared.CurrentUserProfile.TempManager.TempPath, COFEPath.MakeTempPath(RootWrapper.ArchiveFile.ParseName, "")) :
                
                COFEPath.Combine(COFEShared.CurrentUserProfile.TempManager.TempPath, 
                COFEPath.MakeTempPath(RootWrapper.ArchiveFile.ParseName, _currentItem.FileName));
        }

        public override bool Equals(object obj)
        {
            if (obj is SZEntryInfo)
                return Equals(obj as SZEntryInfo);

            return false;
        }

        public bool Equals(SZEntryInfo other)
        {
            return this.CurrentItem.FileName == other.CurrentItem.FileName &&
                   this._rootWrapper.ArchiveFile.ParseName == other._rootWrapper.ArchiveFile.ParseName;
        }

        private string getListPattern()
        {
            return String.Format(RegexPatterns.SevenZipListPattern, Regex.Escape(_currentItem.FileName)); 
        }

        private string getParseName()
        {
            return COFEPath.Combine(RootWrapper.ArchiveFile.ParseName, CurrentItem.FileName);
        }


        public IEnumerable<SZEntryInfo> List()
        {
            int count = 0;
            IEnumerator<ArchiveFileInfo> etor = RootWrapper.list(getListPattern()).GetEnumerator();
            while (etor.MoveNext())
            {
                count++;
                yield return new SZEntryInfo(_rootWrapper, etor.Current);
            }

            //System.Diagnostics.Debug.WriteLine(String.Format("{0} - {1} items listed.", getListPattern(), count));
        }

        public override string ToString()
        {
            return (IsFolder ? "[D]" : "[F]") + RelativePath;
        }

        public override int GetHashCode()
        {
            return (this.CurrentItem.FileName + this._rootWrapper.ArchiveFile.ParseName).GetHashCode();
        }

        #endregion

        #region Data
        
        SevenZipWrapper _rootWrapper = null;
        ArchiveFileInfo _currentItem;
        bool _isRoot;

        #endregion

        #region Public Properties

        public string ListerKey { get; private set; }
        public string TempPath { get { return getTempPath(); }  }
        public string ParseName { get { return getParseName(); } }
        public string RelativePath { get { return _currentItem.FileName; } }
        public string RelativeMask { get { return _currentItem.IsDirectory ? _currentItem.FileName + "\\*" : _currentItem.FileName; } }
        public string Name { get { return CurrentItem.FileName == "" ? RootWrapper.ArchiveFile.Name : COFEPath.GetFileName(CurrentItem.FileName); } }
        public bool IsFolder { get { return CurrentItem.IsDirectory; } }
        public SevenZipWrapper RootWrapper { get { return _rootWrapper; } private set { _rootWrapper = value; } }
        public ArchiveFileInfo CurrentItem { get { return _currentItem; } private set { _currentItem = value; } }
        public string ListPattern { get { return getListPattern(); } }

        #endregion

       
    }
}
